package com.rds.material.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.rds.common.annotation.Log;
import com.rds.common.api.material.domain.MaterialBill;
import com.rds.common.api.material.domain.RdaPartsRel;
import com.rds.common.core.controller.BaseController;
import com.rds.common.core.domain.AjaxResult;
import com.rds.common.core.domain.entity.Document;
import com.rds.common.core.page.TableDataInfo;
import com.rds.common.enums.BusinessType;
import com.rds.common.utils.poi.ExcelUtil;
import com.rds.eco.service.IRdaEcoRelService;
import com.rds.material.dto.*;
import com.rds.material.service.IRdaPartService;
import com.rds.material.service.IRdaPartsRelService;
import com.rds.system.domain.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

/**
 * 【请填写功能名称】Controller
 * 
 * @author ruoyi
 * @date 2023-11-30
 */
@RestController
@RequestMapping("/pms/rel")
public class RdaPartsRelController extends BaseController
{
    @Autowired
    private IRdaPartsRelService rdaPartsRelService;


    @Autowired
    private IRdaEcoRelService rdaEcoRelService;

    @Autowired
    private IRdaPartService rdaPartService;


    /**
     * 查询【请填写功能名称】列表
     */
    @GetMapping("/list")
    public TableDataInfo list(RdaPartsRel rdaPartsRel)
    {
        startPage();
        List<RdaPartsRel> list = rdaPartsRelService.selectRdaPartsRelList(rdaPartsRel);
        return getDataTable(list);
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, RdaPartsRel rdaPartsRel)
    {
        List<RdaPartsRel> list = rdaPartsRelService.selectRdaPartsRelList(rdaPartsRel);
        ExcelUtil<RdaPartsRel> util = new ExcelUtil<RdaPartsRel>(RdaPartsRel.class);
        util.exportExcel(response, list, "【请填写功能名称】数据");
    }

    /**
     * 获取【请填写功能名称】详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(rdaPartsRelService.selectRdaPartsRelById(id));
    }

    /**
     * 获取【请填写功能名称】详细信息
     */
    @PutMapping
    public AjaxResult updateInfo(@RequestBody RdaPartsRel rdaPartsRel)
    {
        return success(rdaPartsRelService.updateRdaPartsRel(rdaPartsRel));
    }


    /**
     * 删除【请填写功能名称】
     */
    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(rdaPartsRelService.deleteRdaPartsRelByIds(ids));
    }

    /**
     * 删除库信息
     */
    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
    @DeleteMapping("/library/{ids}")
    public AjaxResult library(@PathVariable Long[] ids)
    {
        int i = rdaPartService.deleteRdaPartByIds(ids);
        return toAjax(i);
    }

    /**
     * 查询关联表信息
     */
    @GetMapping(value = "/bill")
    public JSONObject RelAndBillList(ServletRequest request)
    {
        return rdaPartsRelService.RelAndBillList(request);
    }

    /**
     * 新增关系
     */
    @PostMapping("/addMaterialAddRel")
    @Log(title = "【新增关系与零件】", businessType = BusinessType.INSERT)
    @Transactional
    public AjaxResult addMaterialAddRel(@RequestBody Map<String,Object> map){
        int number = rdaPartsRelService.addMaterialAddRel(map,"");
        return toAjax(number);
    }

    /**
     * 添加下级
     */
    @PostMapping("/addDownMaterialAddRel")
    @Log(title = "【新增关系与零件】", businessType = BusinessType.INSERT)
    @Transactional
    public AjaxResult addDownMaterialAddRel(@RequestBody Map<String,Object> map){
        int number = rdaPartsRelService.addMaterialAddRel(map,"down");
        return toAjax(number);
    }

    /**
     * 添加上级
     */
    @PostMapping("/addSuperiorMaterialAddRel")
    @Log(title = "【新增关系与零件】", businessType = BusinessType.INSERT)
    @Transactional
    public AjaxResult addSuperiorMaterialAddRel(@RequestBody Map<String,Object> map){
        int number = rdaPartsRelService.addMaterialAddRel(map,"addSuperior");
        return toAjax(number);
    }

    /**
     * 修改【请填写功能名称】
     */
    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
    @PutMapping("/updateMaterialAddRel")
    public AjaxResult updateMaterialAddRel(@RequestBody Map<String,Object> map)
    {
        return toAjax(rdaPartsRelService.updateMaterialAddRel(map));
    }

    /**
     * 材料清单
     */
    @GetMapping("/billofMaterial")
    public TableDataInfo billofMaterial(RdaPartsRel rdaPartsRel)
    {
        List<RdaPartsRel> rdaPartsRels = rdaPartsRelService.billofMaterial(rdaPartsRel);
        ArrayList<MaterialBillAndRdaPartsRel> rdaPartsRelsList = new ArrayList<>();
        for (RdaPartsRel partsRel : rdaPartsRels) {
            MaterialBillAndRdaPartsRel materialBillAndRdaPartsRel = new MaterialBillAndRdaPartsRel(partsRel);
            rdaPartsRelsList.add(materialBillAndRdaPartsRel);
        }
        return getDataTable(rdaPartsRelsList);
    }

    @Log(title = "获取物料版本")
    @GetMapping("/materialVersion")
    public TableDataInfo materialVersion(Long id)
    {
        List<MaterialBill> materialBillList = rdaPartsRelService.materialVersion(id);
        return getDataTable(materialBillList);
    }

    @Log(title = "版本升级")
    @PostMapping("/upgrade")
    public AjaxResult Upgrade(@RequestBody MaterialVersionUpgradeDto materialVersionUpgradeDto)
    {
        rdaPartsRelService.Upgrade(materialVersionUpgradeDto);
        return AjaxResult.success();
    }




    /**
     * 项目反查
     */
    @GetMapping("/referrer")
    public TableDataInfo referrer(@RequestParam Long id){
           return getDataTable(rdaPartsRelService.referrer(id));
    }

    /**
     * 零件基本信息新增文件
     */
    @PreAuthorize("@ss.hasPermi('pms:reimbursement:user:addFile2')")
    @PostMapping("/addFile")
    public AjaxResult addFile(@RequestBody Sharing rdaMemberlistUser){
        return toAjax(rdaPartsRelService.addFile(rdaMemberlistUser));
    }

    /**
     * 复制与剪切
     */
    @PostMapping(value = "/copy")
    @Transactional
    public AjaxResult copywbs(@RequestBody List<Sharing> sharing){
        rdaPartsRelService.copywbs(sharing);
        return AjaxResult.success();
    }

    /**
     * 移除物料
     */
    @Log(title = "移除物料", businessType = BusinessType.DELETE)
    @DeleteMapping("removeEbom/{ids}")
    @Transactional
    public AjaxResult removeEbom(@PathVariable Long[] ids){
        rdaPartsRelService.removeEbom(ids);
        return AjaxResult.success();
    }

    /**
     * 移除物料
     */
    @Log(title = "删除物料", businessType = BusinessType.DELETE)
    @DeleteMapping("delectEbom/{ids}")
    @Transactional
    public AjaxResult delectEbom(@PathVariable Long[] ids){
        rdaPartsRelService.delectEbom(ids);
        return AjaxResult.success();
    }

    /**
     * 插入现有零件作为子级
     */
    @Log(title = "插入现有零件作为子级", businessType = BusinessType.INSERT)
    @PostMapping("/InsertExistAsChild")
    public AjaxResult InsertExistAsChild(@RequestBody Sharing rdaPmsassignRel)
    {
        rdaPartsRelService.InsertExistAsChild(rdaPmsassignRel);
        return AjaxResult.success();
    }

    @Log(title = "插入下一现有零件作为同级", businessType = BusinessType.INSERT)
    @PostMapping("/InsertExistAsLevel")
    public AjaxResult InsertExistAsLevel(@RequestBody Sharing rdaPmsassignRel)
    {
        rdaPartsRelService.InsertExistAsLevel(rdaPmsassignRel);
        return AjaxResult.success();
    }

    @Log(title = "插入下一现有零件作为同级", businessType = BusinessType.INSERT)
    @PostMapping("/InsertExistAsUpper")
    public AjaxResult InsertExistAsUpper(@RequestBody Sharing rdaPmsassignRel)
    {
        rdaPartsRelService.InsertExistAsUpper(rdaPmsassignRel);
        return AjaxResult.success();
    }

    @Log(title = "规范和文档", businessType = BusinessType.INSERT)
    @GetMapping("/doc")
    public TableDataInfo doc(Long id) throws Exception {
//        List<Document> documents = rdaPartsRelService.selectRdaPartsRelList(id);
        List<HashMap<String, Object>> documents = rdaPartsRelService.selectRdaPartsRelList(id);
        return getDataTable(documents);
    }


    @Log(title = "规范和文档", businessType = BusinessType.INSERT)
    @PostMapping("/bindDoc")
    public AjaxResult bindDoc(@RequestBody Sharing rdaPmsassignRel)
    {
        rdaPartsRelService.bindDoc(rdaPmsassignRel);
        return AjaxResult.success();
    }

    /**
     * 重新排序
     */
    @PreAuthorize("@ss.hasPermi('system:eco:query')")
    @GetMapping(value = "/rankSort")
    public AjaxResult rankSort(RdaPartsRel rdaPartsRel)
    {
        rdaPartsRelService.rankSort(rdaPartsRel);
        return success("获取受影响项目");
    }

    /**
     * 视图排序
     */
    @PreAuthorize("@ss.hasPermi('system:eco:query')")
    @PostMapping(value = "/viewSort")
    public AjaxResult viewSort(@RequestBody Sharing rdaPmsassignRel)
    {
        rdaPartsRelService.viewSort(rdaPmsassignRel);
        return success("获取受影响项目");
    }


    /**
     * 项目反查
     */
    @PreAuthorize("@ss.hasPermi('system:eco:query')")
    @GetMapping(value = "/reverseList")
    public TableDataInfo reverseList(Long id)
    {
        return getDataTable(rdaPartsRelService.reverseList(id));
    }

    /**
     * 复制到
     */
    @PreAuthorize("@ss.hasPermi('pms:ebom:remove')")
    @Log(title = "复制到", businessType = BusinessType.INSERT)
    @PostMapping("/copyTo")
    @Transactional
    public AjaxResult copyTo(@RequestBody Sharing rdaRestrainwbsRel){
        rdaPartsRelService.copyTo(rdaRestrainwbsRel);
        return AjaxResult.success();
    }


    /**
     * 多级报告
     */
    @GetMapping("/multilevelReport")
    public TableDataInfo multilevelReport(RdaPartsRel rdaPartsRel,String relation)
    {
        List<RdaPartsRel> rdaPartsRels = new ArrayList<>();
        if ("1".equals(relation)){
            rdaPartsRels = rdaPartsRelService.billofMaterialEbomLevel(rdaPartsRel);
        }else {
            rdaPartsRels = rdaPartsRelService.billofMaterial(rdaPartsRel);
        }
        ArrayList<MaterialBillAndRdaPartsRel> rdaPartsRelsList = new ArrayList<>();
        for (RdaPartsRel partsRel : rdaPartsRels) {
            MaterialBillAndRdaPartsRel materialBillAndRdaPartsRel = new MaterialBillAndRdaPartsRel(partsRel);
            rdaPartsRelsList.add(materialBillAndRdaPartsRel);
        }
        return getDataTable(rdaPartsRelsList);
    }

    /**
     * 多级报告
     */
    @GetMapping("/comprehensiveReport")
    public TableDataInfo comprehensiveReport(RdaPartsRel rdaPartsRel,String relation)
    {
        List<RdaPartsRel> rdaPartsRels = new ArrayList<>();
        if ("1".equals(relation)){
            rdaPartsRels = rdaPartsRelService.billofMaterialEbomLevel(rdaPartsRel);
        }else {
            rdaPartsRels = rdaPartsRelService.billofMaterial(rdaPartsRel);
        }
        ArrayList<MaterialBillAndRdaPartsRel> rdaPartsRelsList = new ArrayList<>();
        for (RdaPartsRel partsRel : rdaPartsRels) {
            MaterialBillAndRdaPartsRel materialBillAndRdaPartsRel = new MaterialBillAndRdaPartsRel(partsRel);
            rdaPartsRelsList.add(materialBillAndRdaPartsRel);
        }
        // 使用流进行合并操作
        List<MaterialBillAndRdaPartsRel> mergedList = rdaPartsRelsList.stream()
                .collect(
                        Collectors.collectingAndThen(
                                Collectors.toMap(
                                        MaterialBillAndRdaPartsRel::getName,
                                        mb -> mb,
                                        (mb1, mb2) -> {
                                            mb1.setQuantity(mb1.getQuantity() + mb2.getQuantity());
                                            return mb1;
                                        }
                                ),
                                map -> new ArrayList<>(map.values())
                        )
                );

        return getDataTable(mergedList);
    }


    /**
     * 对比报告
     */
    @PreAuthorize("@ss.hasPermi('pms:ebom:list')")
    @GetMapping("/compareReport")
    public AjaxResult compareReport(@RequestParam(value = "id") Long id,@RequestParam(value = "type",defaultValue = "0") String type,@RequestParam(value = "name",required = false)String name, @RequestParam(value = "revision",required = false)String revision){
        return AjaxResult.success(rdaPartsRelService.compareReport(id,type,name,revision));
    }

    /**
     * 对比报告同版本号的数据
     */
    @PreAuthorize("@ss.hasPermi('pms:ebom:list')")
    @GetMapping("/compareRevi")
    public AjaxResult compareReport(String code,Long projectid){
        MaterialBill materialBill = new MaterialBill();
        materialBill.setCode(code);
        List<MaterialBill> materialBillList = rdaPartsRelService.selectMaterialBillList(materialBill);

        materialBillList = materialBillList.stream()
                .map(bill -> {
                    RdaPartsRel rdaPartsRel = new RdaPartsRel();
                    rdaPartsRel.setFromid(bill.getId());
                    rdaPartsRel.setToid(bill.getProjectid());
                    List<RdaPartsRel> rdaPartsRels = rdaPartsRelService.selectRdaPartsRelList(rdaPartsRel);
                    if (!rdaPartsRels.isEmpty()) {
                        bill.setId(rdaPartsRels.get(0).getId());
                    }
                    return bill;
                })
                .collect(Collectors.toList());

        return AjaxResult.success(materialBillList);
    }

    /**
     * 更改管理
     */
    @PreAuthorize("@ss.hasPermi('pms:ebom:list')")
    @GetMapping("/changeControl")
    public TableDataInfo changeControl(Long id){
        return getDataTable(rdaPartsRelService.changeControl(id));
    }

    /**
     * 物料引用现有eco
     */
    @Log(title = "物料引用现有eco", businessType = BusinessType.INSERT)
    @PostMapping("/referenceEco")
    public AjaxResult referenceEco(@RequestBody Sharing rdaPmsassignRel)
    {
        rdaPartsRelService.referenceEco(rdaPmsassignRel);
        return AjaxResult.success();
    }

    /**
     * 物料新增eco
     */
    @Log(title = "物料引用现有eco", businessType = BusinessType.INSERT)
    @PostMapping("/addEcoByMaterial")
    public AjaxResult addEcoByMaterial(@RequestBody RdaEcoDto rdaEcoDto)
    {
        rdaPartsRelService.addEcoByMaterial(rdaEcoDto);
        return AjaxResult.success();
    }

    /**
     * 替换为现有零件
     * @param replaceMaterialBillDTO
     * @return
     */
    @PreAuthorize("@ss.hasPermi('pms:ebom:remove')")
    @Log(title = "替换为现有零件", businessType = BusinessType.UPDATE)
    @PostMapping("/replace")
    @Transactional
    public AjaxResult replace(@RequestBody ReplaceMaterialBillDTO replaceMaterialBillDTO)
    {
        //替换id
        if ("0".equals(replaceMaterialBillDTO.getToid().toString())){
            return AjaxResult.error("不能选择根节点");
        }
        rdaPartsRelService.replaceEbom(replaceMaterialBillDTO);
        return AjaxResult.success();
    }


    /**
     * 替换为新零件
     */
    @Log(title = "替换为新零件", businessType = BusinessType.UPDATE)
    @PutMapping("/replaceNew")
    @Transactional
    public AjaxResult replaceNew(@RequestBody Map<String,Object> map){
        rdaPartsRelService.addMaterialAddRel(map,"replacewithNewMaterialBill");
        return AjaxResult.success();
    }
}
